package avicit.bdp.dcs.threshold.utils;

import avicit.bdp.common.dto.request.dds.ProcessSchedulerDto;
import avicit.bdp.common.utils.database.DBUtils;
import avicit.bdp.common.utils.enums.FileType;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dcs.job.dto.JobDTO;
import avicit.bdp.dcs.semistructure.dto.HiveJsonDto;
import avicit.bdp.dcs.task.dto.TaskDTO;
import avicit.bdp.dcs.tools.enums.SyncStatus;
import avicit.bdp.dcs.utils.JdbcConstants;
import avicit.platform6.core.rest.msg.ResponseMsg;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.codec.binary.Hex;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import static org.junit.Assert.assertEquals;

public class TestUtils {

  public static String token;

  public static String PT6_URL;
  public static String PT6_USERNAME;
  public static String PT6_PASSWORD;
  /** 测试环境配置信息 */
  public static String HOSTPORT;

  public static final String username = "avicit2015";
  public static final String password = "avicit2015";

  /** MySQL相关操作； */
  public static final String MYSQL_JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";

  public static String MYSQL_DB_URL;
  public static String MYSQL_USER;
  public static String MYSQL_PASS;

  /** Postgresql相关操作； */
  public static final String POSTGRESQL_JDBC_DRIVER = "org.postgresql.Driver";

  public static String POSTGRESQL_DB_URL;
  public static String POSTGRESQL_USER;
  public static String POSTGRESQL_PASSWD;

  /** Oracle相关操作； */
  public static final String ORACLE_JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver";

  public static String ORACLE_DB_URL;
  public static String ORACLE_USER;
  public static String ORACLE_PASSWD;

  /** 达梦相关操作； */
  public static final String DM_JDBC_DRIVER = "dm.jdbc.driver.DmDriver";

  public static String DM_DB_URL;
  public static String DM_USER;
  public static String DM_PASSWD;

  /** param */
  public static String HIVE_DB_URL;

  public static String HIVE_USER;
  public static String HIVE_PASSWD;

  /** 数据源ID；跟HOSTPORT环境绑定； */
  public static String MYSQL_SRC_DATASOURCE_ID;

  public static String MYSQL_DST_DATASOURCE_ID;
  public static String ORACLE_SRC_DATASOURCE_ID;
  public static String ORACLE_DST_DATASOURCE_ID;
  public static String PG_DATASOURCE_ID;
  public static String HDFS_DATASOURCE_ID;
  public static String IOTDB_DATASOURCE_ID;
  public static String HIVE_DATASOURCE_ID;
  public static String GP_DATASOURCE_ID;
  public static String DM_DATASOURCE_ID;

  @BeforeClass
  public static void init() throws Exception {
    Properties resource = new Properties();
    InputStream in;
    System.out.println("ready to load properties......");
    String propertyPath = System.getProperty("test.file.path");
    if (propertyPath == null || "".equals(propertyPath)) {
      propertyPath = "unittest.properties";
      // 使用ClassLoader加载properties配置文件生成对应的输入流
      in = TestUtils.class.getClassLoader().getResourceAsStream(propertyPath);
      System.out.println("can not find vm option[test.file.path], use default properties");
    } else {
      // 使用FileInputStream加载properties配置文件生成对应的输入流
      in = new FileInputStream(propertyPath);
      System.out.println(
          "read properties from vm option[test.file.path], path is: " + propertyPath);
    }

    // 使用properties对象加载输入流
    resource.load(in);

    PT6_URL = resource.getProperty("test.pt6.address");
    PT6_USERNAME = resource.getProperty("test.pt6.username");
    PT6_PASSWORD = resource.getProperty("test.pt6.password");

    HOSTPORT = resource.getProperty("test.dcs.address");

    MYSQL_DB_URL = resource.getProperty("test.dcs.mysql.url");
    MYSQL_USER = resource.getProperty("test.dcs.mysql.user");
    MYSQL_PASS = resource.getProperty("test.dcs.mysql.password");

    POSTGRESQL_DB_URL = resource.getProperty("test.dcs.postgresql.url");
    POSTGRESQL_USER = resource.getProperty("test.dcs.postgresql.user");
    POSTGRESQL_PASSWD = resource.getProperty("test.dcs.postgresql.password");

    ORACLE_DB_URL = resource.getProperty("test.dcs.oracle.url");
    ORACLE_USER = resource.getProperty("test.dcs.oracle.user");
    ORACLE_PASSWD = resource.getProperty("test.dcs.oracle.password");

    HIVE_DB_URL = resource.getProperty("test.dcs.hive.url");
    HIVE_USER = resource.getProperty("test.dcs.hive.user");
    HIVE_PASSWD = resource.getProperty("test.dcs.hive.password");

    DM_DB_URL = resource.getProperty("test.dcs.dm.url");
    DM_USER = resource.getProperty("test.dcs.dm.user");
    DM_PASSWD = resource.getProperty("test.dcs.dm.password");

    MYSQL_SRC_DATASOURCE_ID = resource.getProperty("test.dcs.mysql.src.datasource.id");
    MYSQL_DST_DATASOURCE_ID = resource.getProperty("test.dcs.mysql.dst.datasource.id");
    ORACLE_SRC_DATASOURCE_ID = resource.getProperty("test.dcs.oracle.src.datasource.id");
    ORACLE_DST_DATASOURCE_ID = resource.getProperty("test.dcs.oracle.dst.datasource.id");
    PG_DATASOURCE_ID = resource.getProperty("test.dcs.pg.datasource.id");
    HDFS_DATASOURCE_ID = resource.getProperty("test.dcs.hdfs.datasource.id");
    IOTDB_DATASOURCE_ID = resource.getProperty("test.dcs.iotdb.datasource.id");
    HIVE_DATASOURCE_ID = resource.getProperty("test.dcs.hive.datasource.id");
    GP_DATASOURCE_ID = resource.getProperty("test.dcs.gp.datasource.id");
    DM_DATASOURCE_ID = resource.getProperty("test.dcs.dm.datasource.id");

    System.out.println("end load properties......");

    token = getToken();
  }

  /** 单个测试用例运行前准备工作 */
  @Before
  public void setUp() {}

  /** 单个测试用例运行后销毁工作 */
  @After
  public void tearDown() {}

  /** 所有用例执行完成后准备工作 */
  @AfterClass
  public static void destroy() {}

  @Test
  public void testReadProperties() {
    System.out.println("HOST_PORT = " + HOSTPORT);
    Assert.assertNotNull(HOSTPORT);
  }

  private static final RestTemplate restTemplate = new RestTemplate();

  /** 创建测试用Table */
  public static void prepareData(String tableName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      stmt = conn.createStatement();
      String delSql = "DROP TABLE IF EXISTS " + tableName + ";";
      stmt.execute(delSql);

      String createSql =
          "CREATE TABLE "
              + tableName
              + "  (\n"
              + "  `id` int(11) NOT NULL AUTO_INCREMENT,\n"
              + "  `time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP,\n"
              + "  PRIMARY KEY (`id`) USING BTREE\n"
              + ") ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT "
              + "= Dynamic;";
      stmt.execute(createSql);

      String insertSql = "INSERT INTO " + tableName + " VALUES (1, '2020-08-26 14:19:33');";
      stmt.execute(insertSql);
      insertSql = "INSERT INTO " + tableName + " VALUES (6, '2020-08-28 14:31:29');";
      stmt.execute(insertSql);

      // 完成后关闭
      stmt.close();
      conn.close();
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      try {
        if (stmt != null) {
          stmt.close();
        }
      } catch (SQLException e) {
        e.printStackTrace();
      }
      try {
        if (conn != null) {
          conn.close();
        }
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  /** 新增一条记录 */
  public static void addData(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      stmt = conn.createStatement();
      String insertSql = "INSERT INTO `" + tblName + "` VALUES (15, '2020-09-01 14:22:47');";
      stmt.execute(insertSql);

      // 完成后关闭
      stmt.close();
      conn.close();
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      try {
        if (stmt != null) {
          stmt.close();
        }
      } catch (SQLException e) {
        e.printStackTrace();
      }
      try {
        if (conn != null) {
          conn.close();
        }
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  /** 新增一条记录,用于定时任务测试 */
  public static void addData2(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行插入
      stmt = conn.createStatement();
      SimpleDateFormat sdf = new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS);
      String insertSql =
          "insert into " + tblName + " values (32, " + "'" + sdf.format(new Date()) + "');";
      System.out.println(insertSql);
      stmt.execute(insertSql);
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 清理测试用Table */
  public static void deleteFromMysql(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      stmt = conn.createStatement();
      String delSql = "DROP TABLE IF EXISTS `" + tblName + "`;";
      stmt.execute(delSql);

      System.out.println(String.format("删除Mysql表%s成功", tblName));
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 批量清理测试用Table */
  public static void batchCleanData(String[] tables) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      for (String tblName : tables) {
        stmt = conn.createStatement();
        String delSql = "DROP TABLE IF EXISTS `" + tblName + "`;";
        stmt.execute(delSql);
      }
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 创建Mysql数据 */
  public static void insert2Mysql(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      stmt = conn.createStatement();
      String delSql = "DROP TABLE IF EXISTS `" + srcTblName + "`;";
      stmt.execute(delSql);

      String createSql =
          "CREATE TABLE `"
              + srcTblName
              + "`  (\n"
              + "  `id` int(11) NOT NULL AUTO_INCREMENT,\n"
              + "  `time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP,\n"
              + "  PRIMARY KEY (`id`) USING BTREE\n"
              + ") ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT "
              + "= Dynamic;";
      stmt.execute(createSql);

      String insertSql = "INSERT INTO `" + srcTblName + "` VALUES (1, '2020-08-26 14:19:33');";
      stmt.execute(insertSql);
      insertSql = "INSERT INTO `" + srcTblName + "` VALUES (6, '2020-08-28 14:31:29');";
      stmt.execute(insertSql);

      System.out.println(String.format("创建Mysql表%s成功", srcTblName));

      // 完成后关闭
      stmt.close();
      conn.close();
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 创建Mysql数据-全字段 */
  public static void insert2MysqlMutilField(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(MYSQL_JDBC_DRIVER);

      // 打开链接
      conn = DriverManager.getConnection(MYSQL_DB_URL, MYSQL_USER, MYSQL_PASS);

      // 执行删除
      stmt = conn.createStatement();
      String delSql = "DROP TABLE IF EXISTS `" + srcTblName + "`;";
      stmt.execute(delSql);

      String createSql =
          "CREATE TABLE `"
              + srcTblName
              + "`  (\n"
              + "  `id` varchar(50) NOT NULL,\n"
              + "  `a` bigint(255) DEFAULT NULL,\n"
              + "  `b` binary(255) DEFAULT NULL,\n"
              + "  `c` bit(6) DEFAULT NULL,\n"
              + "  `d` blob,\n"
              + "  `e` char(255) DEFAULT NULL,\n"
              + "  `f` date DEFAULT NULL,\n"
              + "  `g` datetime DEFAULT NULL,\n"
              + "  `h` decimal(32,0) DEFAULT NULL,\n"
              + "  `i` double(255,0) DEFAULT NULL,\n"
              + "  `j` float(15,0) DEFAULT NULL,\n"
              + "  `l` json DEFAULT NULL,\n"
              + "  `m` int(255) DEFAULT NULL,\n"
              + "  `o` longblob,\n"
              + "  `p` longtext,\n"
              + "  `q` mediumblob,\n"
              + "  `r` mediumint(255) DEFAULT NULL,\n"
              + "  `s` mediumtext,\n"
              + "  `aa` smallint(10) DEFAULT NULL,\n"
              + "  `ab` text,\n"
              + "  `ac` time DEFAULT NULL,\n"
              + "  `ad` timestamp NULL DEFAULT NULL,\n"
              + "  `ae` tinyblob,\n"
              + "  `af` tinyint(255) DEFAULT NULL,\n"
              + "  `ag` tinytext,\n"
              + "  `ah` varbinary(255) DEFAULT NULL,\n"
              + "  `ai` year(4) DEFAULT NULL,\n"
              + "  PRIMARY KEY (`id`)\n"
              + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";

      stmt.execute(createSql);

      String insertSql =
          "INSERT INTO `"
              + srcTblName
              + "` VALUES ('100', 2, NULL, b'000111', NULL, '1', '2023-03-01', '2023-03-01 11:34:00', 3, 3, 3, '3', 3, NULL, '2', NULL, 2, '2', 2, '1', '11:31:00', '2023-03-01 11:34:55', NULL, 1, '1', NULL, 2023);";
      stmt.execute(insertSql);

      System.out.println(String.format("创建Mysql表%s成功", srcTblName));

      // 完成后关闭
      stmt.close();
      conn.close();
    } catch (Exception se) {
      se.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 创建Postgresql数据 */
  public static void insert2Postgresql(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      Class.forName(POSTGRESQL_JDBC_DRIVER);
      conn = DriverManager.getConnection(POSTGRESQL_DB_URL, POSTGRESQL_USER, POSTGRESQL_PASSWD);
      System.out.println("连接35 PG数据库成功！");
      stmt = conn.createStatement();

      // step1:删除已存在表
      String delSql = "DROP TABLE IF EXISTS \"sds\".\"" + srcTblName + "\"";
      stmt.execute(delSql);
      // step2:新建表
      String createSql =
          "CREATE TABLE \"sds\".\""
              + srcTblName
              + "\" (\n"
              + "  \"id\" int4 NOT NULL,\n"
              + "  \"time\" timestamp(6)\n"
              + ")";
      stmt.executeUpdate(createSql);
      // step3:插入一条数据
      String insertSql =
          "INSERT INTO \"sds\".\"" + srcTblName + "\" VALUES (1, '2020-08-26 14:19:33');";
      stmt.executeUpdate(insertSql);
      stmt.close();
      conn.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.err.println(e.getClass().getName() + ": " + e.getMessage());
      System.exit(0);
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }

    System.out.println(String.format("创建PG表%s成功", srcTblName));
  }

  /** 删除Postgresql数据 */
  public static void deleteFromPostgresql(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      Class.forName(POSTGRESQL_JDBC_DRIVER);
      conn = DriverManager.getConnection(POSTGRESQL_DB_URL, POSTGRESQL_USER, POSTGRESQL_PASSWD);
      System.out.println("连接35 PG数据库成功！");
      stmt = conn.createStatement();
      String delSql = "DROP TABLE IF EXISTS \"sds\".\"" + tblName + "\"";
      stmt.execute(delSql);
      stmt.close();
      conn.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.err.println(e.getClass().getName() + ": " + e.getMessage());
      System.exit(0);
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }

    System.out.println(String.format("删除PG表%s成功", tblName));
  }

  /** 创造Oracle数据源 */
  public static void insert2Oracle(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载oracle驱动
      Class.forName(ORACLE_JDBC_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(ORACLE_DB_URL, ORACLE_USER, ORACLE_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // step4:删除已存在的表
      //            String delSql = "drop table testunit";
      //            stmt.executeUpdate(delSql);

      // setp5:创建表
      String createSql =
          "create table "
              + srcTblName
              + "(id int primary key     not null,"
              + " age     int    not null)";
      stmt.executeUpdate(createSql);

      // step6:插入一条数据
      String insertSql = "insert into " + srcTblName + " values (15, 33)";
      stmt.executeUpdate(insertSql);

      System.out.println(String.format("创建Oracle表%s成功", srcTblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 创造Oracle数据源-全字段 */
  public static void insert2OracleMutilField(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载oracle驱动
      Class.forName(ORACLE_JDBC_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(ORACLE_DB_URL, ORACLE_USER, ORACLE_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // setp5:创建表
      String createSql =
          "create table "
              + srcTblName
              + "("
              + "  id VARCHAR2(50) primary key not null,\n"
              + "  b  FLOAT,\n"
              + "  d  BLOB,\n"
              + "  e  CHAR(10),\n"
              + "  f  CLOB,\n"
              + "  g  DATE,\n"
              + "  h  INTEGER,\n"
              + "  i  FLOAT,\n"
              + "  m  FLOAT(25),\n"
              + "  n  TIMESTAMP(6),\n"
              + "  s  NUMBER(10,3),\n"
              + "  t  RAW(50),\n"
              + "  u  LONG RAW,\n"
              + "  v  NVARCHAR2(50),\n"
              + "  w  NCHAR(10),\n"
              + "  x  NCLOB,\n"
              + "  y  CHAR(20)\n"
              + ")";

      stmt.executeUpdate(createSql);

      // step6:插入一条数据
      String insertSql =
          "insert into "
              + srcTblName
              + "(ID,B,D,E,F,G,H,I,M,N,S,T,U,V,W,X,Y) values \n"
              + "(2000, 5.9, null, 'qq', 'www',null,600,22,556.67,null,10.400,null,null,12,1,'5',9)";
      stmt.executeUpdate(insertSql);

      System.out.println(String.format("创建Oracle表%s成功", srcTblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 清理Oracle数据源 */
  public static void deleteFromOracle(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载oracle驱动
      Class.forName(ORACLE_JDBC_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(ORACLE_DB_URL, ORACLE_USER, ORACLE_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // step4:删除已存在的表
      String delSql = "drop table " + tblName;
      stmt.executeUpdate(delSql);

      System.out.println(String.format("删除Oracle表%s成功", tblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 创造DM数据源 */
  public static void insert2Dm(String srcTblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载dm驱动
      Class.forName(DM_JDBC_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(DM_DB_URL, DM_USER, DM_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // setp5:创建表
      String createSql =
          "create table "
              + srcTblName
              + "(id int primary key     not null,"
              + " age     int    not null)";
      stmt.executeUpdate(createSql);

      // step6:插入一条数据
      String insertSql = "insert into " + srcTblName + " values (15, 33)";
      stmt.executeUpdate(insertSql);

      System.out.println(String.format("创建DM表%s成功", srcTblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 清理DM数据源 */
  public static void deleteFromDm(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载dm驱动
      Class.forName(DM_JDBC_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(DM_DB_URL, DM_USER, DM_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // step4:删除已存在的表
      String delSql = "drop table " + tblName;
      stmt.executeUpdate(delSql);

      System.out.println(String.format("删除DM表%s成功", tblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  /** 清理Hive数据源 */
  public static void deleteFromHive(String tblName) {
    Connection conn = null;
    Statement stmt = null;
    try {
      // step1:加载oracle驱动
      Class.forName(JdbcConstants.HIVE_DRIVER);

      // step2:驱动成功后进行连接
      conn = DriverManager.getConnection(HIVE_DB_URL, HIVE_USER, HIVE_PASSWD);

      // step3:获得连接
      stmt = conn.createStatement();

      // step4:删除已存在的表
      String delSql = "DROP TABLE IF EXISTS " + tblName;
      stmt.executeUpdate(delSql);

      System.out.println(String.format("删除Hive表%s成功", tblName));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DBUtils.closeResource(conn, stmt, null);
    }
  }

  public static void createFile(String fileName) {
    try {
      File file = new File(System.getProperty("user.dir") + "/" + fileName);
      if (!file.exists()) {
        file.createNewFile();
      }
      FileWriter fileWriter = new FileWriter(file.getName(), true);
      fileWriter.write("name,age,work");
      fileWriter.close();
      System.out.println("文件创建成功！");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void deleteFile(String fileName) {
    try {
      File file = new File(System.getProperty("user.dir") + "/" + fileName);
      file.delete();
      System.out.println("删除文件成功！");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static HttpEntity<MultiValueMap<String, Object>> buildUploadFileHttpEntity(
      MultiValueMap<String, Object> form) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.valueOf("multipart/form-data"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));

    HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(form, headers);
    return httpEntity;
  }

  public static HttpEntity<String> buildPostHttpEntity(String param) {
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  public static HttpEntity<String> buildDeleteHttpEntity(String param) {
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /**
   * 获取一个文件的md5值(可处理大文件)
   *
   * @return md5 value
   */
  public static String getMD5(File file) {
    FileInputStream fileInputStream = null;
    try {
      MessageDigest MD5 = MessageDigest.getInstance("MD5");
      fileInputStream = new FileInputStream(file);
      byte[] buffer = new byte[8192];
      int length;
      while ((length = fileInputStream.read(buffer)) != -1) {
        MD5.update(buffer, 0, length);
      }
      return new String(Hex.encodeHex(MD5.digest()));
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    } finally {
      try {
        if (fileInputStream != null) {
          fileInputStream.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /** 保存数据源 */
  public static HttpEntity<String> buildSaveDataSourceParas(
      int jobType, String jobName, String srcDsId, String dstDsId, int syncMode) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setName(jobName);
    jobDTO.setJobType(jobType);
    jobDTO.setSrcDatasourceId(srcDsId);
    jobDTO.setDstDatasourceId(dstDsId);
    jobDTO.setSyncMode(syncMode);

    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<>(param, headers);
  }

  /** 保存表映射关系参数 */
  public static HttpEntity<String> buildSaveTblMapping(
      int jobType, String jobId, String srcTblName, String dstTableName) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    jobDTO.setTransferType("1,2");
    jobDTO.setProcessMode(1);
    jobDTO.setSelectedTable(
        "[{\"src_table\":\"" + srcTblName + "\",\"dst_table\":\"" + dstTableName + "\"}]");
    HiveJsonDto hiveJsonDto = new HiveJsonDto();
    hiveJsonDto.setFileType(FileType.TEXT.getCode());
    hiveJsonDto.setFileSeparator(",");
    //        hiveJsonDto.setDefaultFS("hdfs://192.168.0.28:8020");
    jobDTO.setExtraParams(JSONObject.toJSONString(hiveJsonDto));

    // 数据同步
    if (jobType == 1) {
      jobDTO.setJobType(1);
    }
    // 数据同步-增量同步
    else if (jobType == 2) {
      jobDTO.setSyncInterval(1800);
      jobDTO.setTableInit(1);
      jobDTO.setJobType(2);
    } else if (jobType == 3) {
      jobDTO.setSyncInterval(60);
      jobDTO.setTableInit(1);
      jobDTO.setJobType(3);
    }

    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 任务配置检查 */
  public static HttpEntity<String> buildCheckTaskConfig(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 保存预检查参数 */
  public static HttpEntity<String> buildPreChecks(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 更新任务信息 */
  public static HttpEntity<String> buildUpdateTask(
      int jobType, String taskId, String srcTblName, String dstTableName) {
    TaskDTO taskDTO = new TaskDTO();
    taskDTO.setId(taskId);
    if (jobType == 2) {
      taskDTO.setDstTableName(dstTableName);
    } else if (jobType == 3) {
      taskDTO.setDstTableName(dstTableName);
    }
    taskDTO.setSrcTableName(srcTblName);
    taskDTO.setFilterCondition(null);
    taskDTO.setModifyColumn(0);
    taskDTO.setSyncMode(0);
    taskDTO.setSyncConditionField(1);
    taskDTO.setUpdateHistoryData(1);
    taskDTO.setFieldName("time");
    // 设置定时时间，开始同步时间2020/08/31 18:02:05
    taskDTO.setSyncTimePoint(new Date(1598868125000L));
    String param11 = JSONObject.toJSONString(taskDTO);
    HttpHeaders headers11 = new HttpHeaders(); // 创建一个头部对象
    headers11.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers11.add("X-Access-Token", token);
    headers11.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers11.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param11, headers11);
  }

  /** 保存Job状态 */
  public static HttpEntity<String> buildUpdateJobStatus(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    jobDTO.setJobStatus(SyncStatus.NOT_STARTED.getCode());
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 启动Job */
  public static HttpEntity<String> buildStartJob(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 启用Job */
  public static HttpEntity<String> buildReleaseJob(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    jobDTO.setEnable(1);
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** 删除Job */
  public static HttpEntity<String> buildDeleteJob(String jobId) {
    JobDTO jobDTO = new JobDTO();
    jobDTO.setId(jobId);
    String param = JSONObject.toJSONString(jobDTO);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(param, headers);
  }

  /** Get方法需要的HttpEntity */
  public static HttpEntity<String> buildGetHttpEntity() {
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(null, headers);
  }

  /** 保存定时信息 */
  public static HttpEntity<String> buildSaveScheduleHttpEntity(String jobId) {
    ProcessSchedulerDto processSchedulerDto = new ProcessSchedulerDto();
    processSchedulerDto.setProcessDefinitionId(jobId);
    processSchedulerDto.setCrontab("0 0/1 * * * ?"); // 从当前时间每隔2min执行一次
    Date currDate = new Date();
    long uninxCurrDate = currDate.getTime();
    processSchedulerDto.setStartTime(new Date(uninxCurrDate - 60 * 1000)); // 当前时间前1mmin
    processSchedulerDto.setEndTime(new Date(uninxCurrDate + 10 * 60 * 1000)); // 当前时间后10min
    processSchedulerDto.setFailureStrategy(1);

    String param = JSONObject.toJSONString(processSchedulerDto);
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));

    return new HttpEntity<String>(param, headers);
  }

  /** 获取创建的JobId */
  public static String getJobId(String jobId) {
    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    ResponseEntity<ResponseMsg> result =
        restTemplate.exchange(
            HOSTPORT
                + "/api/bdp/dcs/job/JobRest/getJobList"
                + "?jobStatus&sort&name=processTest1&jobType=1&currentPage=1&pageSize=10",
            HttpMethod.GET,
            buildGetHttpEntity(),
            ResponseMsg.class);
    ResponseMsg body = result.getBody();
    LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) body.getResponseBody();
    List<Object> finalBody = (List<Object>) map.get("result");
    for (Object obj : finalBody) {
      LinkedHashMap<String, String> jobObj = (LinkedHashMap<String, String>) obj;
      JobDTO jobInfo = JSON.parseObject(JSON.toJSONString(jobObj), JobDTO.class);
      if (jobInfo.getName().equals("processTest1")) {
        jobId = jobInfo.getId();

        return jobId;
      }
    }

    return null;
  }

  public static void handleFailedRequest(ResponseEntity<ResponseMsg> result) {
    if (result != null && result.getBody() != null) {
      String retCode = result.getBody().getRetCode();
      if ("500".equals(retCode)) {
        System.out.println("=============================");
        System.out.println("==========请求失败============");
        System.out.println(result.getBody().getErrorDesc());
        System.out.println("=============================");
      }
    } else {
      System.out.println("请求失败，未获取到请求返回体");
    }
  }

  public static HttpEntity<String> buildGetHttpEntity(String token) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("X-Access-Token", token);
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<String>(null, headers);
  }

  public static String getToken() {
    ResponseEntity<ResponseMsg> result =
        restTemplate.postForEntity(
            TestUtils.PT6_URL, TestUtils.buildLoginParam(), ResponseMsg.class);
    TestUtils.handleFailedRequest(result);
    assertEquals("200", result.getBody().getRetCode());
    // 获取token
    ResponseMsg responseMsg = result.getBody();
    Map<String, String> responseBody = (Map<String, String>) responseMsg.getResponseBody();
    String token = responseBody.get("token");

    return token;
  }

  public static HttpEntity<String> buildLoginParam() {
    JSONObject param = new JSONObject();
    param.put("autoLogin", true);
    param.put("username", PT6_USERNAME);
    param.put("password", PT6_PASSWORD);

    HttpHeaders headers = new HttpHeaders(); // 创建一个头部对象
    headers.setContentType(MediaType.valueOf("application/json; charset=UTF-8"));
    headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
    headers.add(
        "Authorization",
        "Basic " + Base64.getUrlEncoder().encodeToString((username + ":" + password).getBytes()));
    return new HttpEntity<>(param.toJSONString(), headers);
  }

  public static void main(String[] args) {
    // TestUtils.insert2Oracle();
    // TestUtils.insert2Postgresql();
    // TestUtils.deleteFromOracle("UNIT_PG_ORACLE_TEST");
  }
}
